【第1271期】Webpack4+ 多入口程序构建
前言
今日早读文章由富途@Jin分享。
正文从这开始~
其实,说实话这篇文章的由来也是有很多的原因在里面的。在这之前,我也做过不少的项目。有新的项目,也有旧的项目。通过对旧项目的不断研究,改进。再结合自己的理解,将新的构建应用到新的项目中。经过时间的积累,慢慢的就有了一套感觉上还比较适合的webpack前端构建规范。
那这里来说说,webpack4+构建上的一些事吧。
多入口的意思大概就是,访问不同页面的时候,主要的前端JS功能文件是不同的。最好的对比和区别就是SPA单页面应用,每个页面引入的文件都是同一份JS文件。
我期望的构建是:
一气呵成(编码过程爽不爽)
极大程度脱离后端语言限制(解耦)
多入口(多入口,多页面)
一气呵成,意味着项目从你执行git clone
,拉取代码开始,直到你git push
推送代码。这之间,所有与编码无关的,是一气呵成的,并不需要你过多的配置。希望做到的就是编码的极致体验。整个过程,期望开发人员关心的只有一件事,就是自己编写的代码是否OK。
那也意味着webpack构建需要做更多的事。
说起脱离后端语言,这并不是什么好事,只不过要看项目合不合适。在最近写的项目里面,使用的是vue + Node.js
。使用vue ,一般意味着模版文件里面其他很少有Node.js模版(例如:jade,swig)代码,也很少有前端代码。也就是一个空壳页面,做过SPA单页面应用的应该比较熟悉。
那也就是这个空壳页面,其实和后端语言没有太大的耦合关系。那也意味着,我可以极大程度的做到前后端代码解耦。这是什么意思?
试想一下,自己在开发过程中,需要关注的无非就2个东西:页面,静态资源。编码上与后端有耦合的就是只有页面,就像上面说的,使用vue做SPA,其实页面里面其实并没有和后端有耦合。
也就说,这为前后端结构上解耦,提供了便利。前端所有资源可以独立出来,只要保证,通过构建之后,能将页面,静态资源生成到指定项目目录即可。
那构建这里就是由webpack来做。
上图中已经标明:
client:是放前端资源目录
server:是放后端资源的目录。这里假如后端为Node.js
static:是静态资源目录。也就是js/css文件放置的地方
那这里就引出了一个值得先思考的问题,webapck构建的目的是什么?落实到工程项目里面,构建的目的又是什么?
结合上面的目录结构图,如果说webpack的目的是将静态资源打包编译;那么在工程上,就是将前端资源client
目录资源通过webpack构建到指定的static
和server/views
目录。
那这样是不是就做到了极大程度的解耦呢。
那如何在单入口的webpak构建工程上进行修改变为多入口构建工程?这就是今天这篇文章需要解决的问题,也是我一直以来需要解决的问题,也是写这篇文章的初衷。
面对这个多入口程序构建问题,这里先从当前现状说起吧。
注意:以下的所有内容都是在单入口的基础上进行讲述的,相关demo在这里:webpack案例:https://github.com/Yi-love/webpack4-demo
webpack构建现状
一直以来,webpack构建我只做了单入口构建。也就是大家熟悉的SPA。这也并没有影响到项目的运行,因为项目功能单一,目标明确,资源文件不会太大,所以打包压缩之后,出来的文件也不会很大,适当的进行拆分就可以。
如图,构建很简单,单入口,单页面。所有的文件都是通过main.js
和其引入的子模块引入,形成单入口。作为经典的SPA项目,就一个入口页面index.html
,前端跳转由前端路由和后端路由协作完成。
那么需要webpack做的事情其实就很好理解了:
引入对应文件的模块解析。例如:
vue-loader
,babel-loader
,css-loader
等提取css为外部引入,通过
link
标签引入文件压缩
大文件拆分
公共文件提取为独立文件
通过
html-webpack-plugin
将所有依赖的js/css等静态资源注入模版文件,生成目标文件保存到指定服务器模版文件目录
都说了,其实前端最后需要处理的文件大概率就3个html
,js
,css
。
demo详情地址–>> https://github.com/Yi-love/webpack4-demo/tree/step_0
webpack4+ 多入口构建思路
既然都已经知道单入口构建怎么玩的了。那么就来思考一下webpack多入口构建怎么玩呗。
先不说,webpack怎么配置。从需求上来说,不就是期望:
有很多的入口文件
有很多的html模版文件生成。这里会生成到
server/views
目录html模版文件引入自己模块需要的js/css等静态资源即可,其他模块的不引入,以免产生冗余代码
上图的静态资源js/css会生成并保存到static
目录。
也就是说上图的pagea.js
入口文件,通过webpack构建之后,只会注入pagea.html
。而不会注入pageb.html
。
这里其实难点,就一个:如何让对应的入口文件的html模版文件,引入只与本模块有关的js/css。
webpack4+ 多入口构建配置实战
那不废话,实战中要如何配置呢?这恐怕并不是只有我一个人想知道。其实上面的每个问题在这里都有解决的方案。
如图,可以看到多入口配置,超级简单在entry
添加对应模块入口即可。
entry:{//入口文件
pagea:'./client/pagea/index.js',
pageb:'./client/pageb/index.js'
}
这里demo里面有2个入口文件pagea.js
和pageb.js
。
针对这个如何让对应的入口文件的html模版文件,引入只与本模块有关的js/css问题。
可以通过html-webpack-plugin
解决。首先配置多个html-webpack-plugin
实例对象,然后指定每个实例对象需要引入的chunks
文件即可。
new HtmlWebpackPlugin({
filename: './../../server/views/pagea.html',
chunks:['pagea'],
template: path.resolve(__dirname , './client/template.html')
}),
new HtmlWebpackPlugin({
filename: './../../server/views/pageb.html',
chunks:['pageb'],
template: path.resolve(__dirname , './client/template.html')
})
这里配置很简单。pagea.html
配置只引入pagea.js
。当需要引入多个的时候只需要在数组里面添加对应的模块名称即可。
配置完了,来看看结果如何吧。
执行npm install
先下载完所需要的模块,再通过执行webpack
命令进行构建。
webpack请全局安装,需要 v4.5+。
可以看到,通过webpack打包编译,生成了我们想要的pagea.html
和pageb.html
。并且js文件注入正常。
那现在可执行npm run develop
命令启动node.js服务。在浏览器打开127.0.0.1:4000
就看到了页面了。
pagea.html
和pageb.html
,引入正常,并正常运行。大功告成!!!!
demo详情地址–>> https://github.com/Yi-love/webpack4-demo/tree/step_1
webpack4+ 优化
当你以为一切回归平静时,其实才是挑战的开始。要做到多入口,其实感觉还是挺简单的。要做的好,其实距离还是很远的。再往下的篇幅其实已经和多口构建没有多少关系了。主要是一些基于webpack4+ 优化的点,也就是遇到相关问题的解决方案。
Split Chunks模块拆分
项目小的时候,感觉什么都是那么爽。啥事也没有。可是项目一旦变得复杂,那么其实很多之前没有遇到的问题就会暴露无遗。
当我在pagea.js
尝试引入vue
,tui-chart
图表模块的时候,发现了打包出来的文件过于庞大,达到了2.2MB
,即使压缩之后一样。
那么是时候引入文件拆分了,因为webpack4+之后,并不建议再使用CommonChunks
模块,所以使用新的官方推荐的SplitChunks
模块。
通过在webpack的plugin
里面添加:
new webpack.optimize.SplitChunksPlugin({
chunks: 'all',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '-',
name: true,
cacheGroups: {
vue: {
test: /[\\/]node_modules[\\/]vue[\\/]/,
priority: -10,
name: 'vue'
},
'tui-chart': {
test: /[\\/]node_modules[\\/]tui-chart[\\/]/,
priority: -20,
name: 'tui-chart'
}
}
})
添加splitChunks方式有多种,上面只是其中一种。
通过在cacheGroups
里面设置公共模块,达到模块复用。需要注意的就是,在html-webpack-plugin
实例中引入chunks
时,需要加入对应的模块。
new HtmlWebpackPlugin({
filename: './../../server/views/pagea.html',
chunks:['vue','tui-chart','pagea'],
template: path.resolve(__dirname , './client/template.html')
})
上面的pagea.html
不仅需要引入pagea
,还需要而为引入vue
和tui-chart
。
通过上图,最后看到打包拆分出来的js文件体积还是很可观的。
MiniCssExtract提取为外部CSS
说完了JavaScript的体积拆分,其实CSS上面也有一个问题。就是,我并没有在上面的demo中做到通过link
标签引入。这里将解决这个问题。
webpack4+ 提供了一个新的模块叫做MiniCssExtract。这个模块就可以处理.css
外链引入的问题。
首先在rules
里面配置:
{
test: /\.s?[ac]ss$/,//postcss-loader 依赖 postcss-config.js
use: [MiniCssExtractPlugin.loader,'css-loader','postcss-loader','sass-loader']
}
主要是将原来的style-loader
替换成MiniCssExtractPlugin.loader
。如果需要区分环境,进行不同引入也是可以的。
然后需要在下面进行plugins
引入:
new MiniCssExtractPlugin({ //提取为外部css代码
filename:'[name].css?v=[contenthash]'
})
当一切完成之后。执行相关命令。
可以看到,生成的html文件成功的引入了自己需要的文件。
是不是成功了呢? 哈哈。。。。。
赶紧去验证吧!!!!!!一定要验证哦。。。。。。。。。。
demo详情地址–>> 多入口优化案例:https://github.com/Yi-love/webpack4-demo/tree/step_2
总结
大体上,webpack4+构建和其他版本的没有多大区别,最多就是模块的使用有点不同。不过对于我来说,解决了我原来纠结的多入口构建问题。但同时这也是一个demo,算不上是一个完整的构建。还缺很多的东西,但是基础已经在这里了,所以可以在此基础上优化,最终达到自己想要的构建配置。
最后有一个问题,那就是所有打包后生成的文件入不入版本库呢?
这里我给出所谓答案在这篇文章:小马的大前端之路–Node.js初探:https://futu.im/posts/2017-07-26-first-time-use-node.js/
最后,为你推荐
关于本文
作者:@Jin
原文:https://futu.im/posts/2018-05-07-webpack4/